Skip to content

Instantly share code, notes, and snippets.

@keshakot
Created April 26, 2020 22:40
Show Gist options
  • Save keshakot/6cf070110bf6d02cfcdbfbb7b89ed2c8 to your computer and use it in GitHub Desktop.
Save keshakot/6cf070110bf6d02cfcdbfbb7b89ed2c8 to your computer and use it in GitHub Desktop.
#include "stm32f030x8.h"
/*
SPI functions (interrupt driven)
*/
/*
#define BUFF_SIZE 32
volatile uint8_t I2C1_Buffer_Tx[BUFF_SIZE], I2C1_Buffer_Rx[BUFF_SIZE];
volatile uint32_t I2C1_Tx1_Counter = 0, I2C1_Rx1_Counter = 0;
*/
/* Function declarations */
/*----------------------------------------------------------------------------*/
/* SPI_1 */
void SPI1_IRQHandler(void);
void SPI1_Init();
void SPI_Init(SPI_TypeDef *SPIx);
void SPI_Write(SPI_TypeDef *SPIx, uint8_t *tx_buf, uint8_t *rx_buf, uint8_t len);
void SPI_Read(SPI_TypeDef *SPIx, uint8_t *rx_buf, uint8_t len);
/*----------------------------------------------------------------------------*/
/*
Initializes SPI1
NSS - (Pin 20 / PA4)
SCK - (Pin 21 / PA5)
MISO - (Pin 22 / PA6)
MOSI - (Pin 23 / PA7)
*/
void SPI1_Init(){
//Enable SPI1 clock, selecting SYSCLK as the clock source
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; //Enable SPI1 clock
RCC->APB2RSTR |= RCC_APB2RSTR_SPI1RST;
RCC->APB2RSTR &= ~RCC_APB2RSTR_SPI1RST;
// Init NSS pin
GPIO_port_enable(RCC_AHBENR_GPIOAEN); //Enable GPIOA clock
GPIOA->MODER &= ~(GPIO_MODER_MODER4_Msk); //Set to alternative function mode
GPIOA->MODER |= GPIO_MODER_MODER4_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_4; //Push pull
GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEEDR4_0; //Set speed to low
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR4_Msk; //Set PUPDR to pull up
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR4_0;
GPIOA->AFR[0] &= ~(GPIO_AFRL_AFSEL6_Msk); //Set the alternative function to AF0
// Init SCK pin
GPIOA->MODER &= ~(GPIO_MODER_MODER5_Msk); //Set to alternative function mode
GPIOA->MODER |= GPIO_MODER_MODER5_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_5; //Push pull
GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEEDR5_0; //Set speed to low
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR5_Msk; //Set PUPDR to pull up
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR5_0;
GPIOA->AFR[0] &= ~(GPIO_AFRL_AFSEL5_Msk); //Set the alternative function to AF0
// Init MISO pin
GPIOA->MODER &= ~(GPIO_MODER_MODER6_Msk); //Set to alternative function mode
GPIOA->MODER |= GPIO_MODER_MODER6_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_6; //Push pull
GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEEDR6_0; //Set speed to low
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR6_Msk; //Set PUPDR to pull down
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR6_1;
GPIOA->AFR[0] &= ~(GPIO_AFRL_AFSEL6_Msk); //Set the alternative function to AF0
// Init MOSI pin
GPIOA->MODER &= ~(GPIO_MODER_MODER7_Msk); //Set to alternative function mode
GPIOA->MODER |= GPIO_MODER_MODER7_1;
GPIOA->OTYPER &= ~GPIO_OTYPER_OT_7; //Push pull
GPIOA->OSPEEDR &= ~GPIO_OSPEEDR_OSPEEDR7_0; //Set speed to low
GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR7_Msk; //Set PUPDR to pull down
GPIOA->PUPDR |= GPIO_PUPDR_PUPDR7_1;
GPIOA->AFR[0] &= ~(GPIO_AFRL_AFSEL7_Msk); //Set the alternative function to AF0
// Final init
SPI_Init(SPI1);
}
/*
Initializes SPI registers for the provided SPI interface
@param SPIx SPI_TypeDef * the SPI interface to initialize
*/
void SPI_Init(SPI_TypeDef *SPIx){
SPIx->CR1 &= ~SPI_CR1_SPE; // Disable SPI
SPIx->CR1 &= ~SPI_CR1_RXONLY; // Configure full duplex mode
SPIx->CR1 &= ~SPI_CR1_BIDIMODE; // Disable bidirectional data mode
SPIx->CR1 &= ~SPI_CR1_BIDIOE; // Disable output in bidirectional mode
SPIx->CR2 &= ~SPI_CR2_DS; // Configure data frame format to 8 bit mode
SPIx->CR2 |= SPI_CR2_DS_0 | SPI_CR2_DS_1 | SPI_CR2_DS_2;
SPIx->CR1 &= ~SPI_CR1_LSBFIRST; // Set bit order to MSB first
SPIx->CR1 &= ~SPI_CR1_CPHA; // Set the first clock transition to be the first data capture edge
SPIx->CR1 &= ~SPI_CR1_CPOL; // Set clock polarity to 0 when idle
SPIx->CR1 &= 0xFFC7; // Set SPI clock to SYSCLK/2 = 4MHz
SPIx->CR1 &= ~SPI_CR1_CRCEN; // Disable hardware CRC calculation
SPIx->CR2 &= ~SPI_CR2_FRF; // Set frame format to Motorola mode
SPIx->CR1 |= SPI_CR1_SSM; // Enable software slave management
SPIx->CR1 |= SPI_CR1_MSTR; // Set self as master
SPIx->CR1 |= SPI_CR1_SSI; // Manage slave selection with software
SPIx->CR2 |= SPI_CR2_NSSP; // Enable NSS pulse management
SPIx->CR2 |= SPI_CR2_FRXTH; // Set flag when RXNE buffer is 8 bits full
//SPIx->CR2 &= ~SPI_CR2_FRXTH; // Set flag when RXNE buffer is 16 bits full
SPIx->CR1 |= SPI_CR1_SPE; // Enable SPI
}
/*
Send data on a SPI link
@param SPIx SPI_TypeDef * the SPI interface to send on
@param tx_buf uint8_t * the data to send
@param rx_buf uint8_t * where to store received data
@param len uint8_t the length of the data to be sent
*/
void SPI_Write(SPI_TypeDef *SPIx, uint8_t *tx_buf, uint8_t *rx_buf, uint8_t len){
uint8_t i = 0;
for(i=0; i<len; i++){
// Transmit
while((SPIx->SR & SPI_SR_TXE) != SPI_SR_TXE);
SPIx->DR = tx_buf[i];
// Receive
//while((SPIx->SR & SPI_SR_RXNE) != SPI_SR_RXNE);
//rx_buf[i] = SPIx->DR;
}
// Wait for busy flag to be cleared
while((SPIx->SR & SPI_SR_BSY) == SPI_SR_BSY);
}
/*
Receive data on a SPI link
@param SPIx SPI_TypeDef * the SPI interface to receive on
@param rx_buf uint8_t * where to store received data
@param len uint8_t the length of the data to be received
*/
void SPI_Read(SPI_TypeDef *SPIx, uint8_t *rx_buf, uint8_t len){
uint8_t i = 0;
for(i=0; i<len; i++){
// Transmit
while((SPIx->SR & SPI_SR_TXE) != SPI_SR_TXE);
SPIx->DR = 0xFF; // dummy byte
// Receive
while((SPIx->SR & SPI_SR_RXNE) != SPI_SR_RXNE);
rx_buf[i] = SPIx->DR;
}
// Wait for busy flag to be cleared
while((SPIx->SR & SPI_SR_BSY) == SPI_SR_BSY);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment